package com.qimu.saiyou.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qimu.saiyou.common.ErrorCode;
import com.qimu.saiyou.constant.CommonConstant;
import com.qimu.saiyou.exception.BusinessException;
import com.qimu.saiyou.exception.ThrowUtils;
import com.qimu.saiyou.mapper.CompetitionMapper;
import com.qimu.saiyou.model.dto.competition.CompetitionQueryRequest;
import com.qimu.saiyou.model.entity.Competition;
import com.qimu.saiyou.model.entity.User;
import com.qimu.saiyou.model.vo.CompetitionVO;
import com.qimu.saiyou.model.vo.UserVO;
import com.qimu.saiyou.service.CompetitionService;
import com.qimu.saiyou.service.UserService;
import com.qimu.saiyou.utils.RedissonLockUtil;
import com.qimu.saiyou.utils.SqlUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: FeiXiang
 * @description 针对表【competition(竞赛)】的数据库操作Service实现
 * @createDate 2024-02-25 16:40:08
 */
@Service
public class CompetitionServiceImpl extends ServiceImpl<CompetitionMapper, Competition>
        implements CompetitionService {

    @Resource
    private UserService userService;

    @Resource
    private RedissonLockUtil redissonLockUtil;

    @Override
    public void validCompetition(Competition competition, boolean add) {
        if (competition == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Long id = competition.getId();
        String competitionName = competition.getCompetitionName();
        String tags = competition.getTags();
        String competitionAvatarUrl = competition.getCompetitionAvatarUrl();
        Long maxNum = competition.getMaxNum();
        Long userId = competition.getUserId();
        String competitionStatus = competition.getCompetitionStatus();
        Integer competitionType = competition.getCompetitionType();
        Integer competitiveMode = competition.getCompetitiveMode();
        Long teamMaxNum = competition.getTeamMaxNum();
        String announce = competition.getAnnounce();
        String rules = competition.getRules();
        String address = competition.getAddress();
        String reward = competition.getReward();
        String signUpDeadline = competition.getSignUpDeadline();
        String endTime = competition.getEndTime();
        Long examId = competition.getExamId();

        // 创建时，参数不能为空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(competitionName, tags, signUpDeadline, endTime), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(ObjectUtils.anyNull(competitionType, competitiveMode, teamMaxNum), ErrorCode.PARAMS_ERROR);
            ThrowUtils.throwIf(StringUtils.isBlank(competitionName), ErrorCode.PARAMS_ERROR, "竞赛名称不能为空");
            ThrowUtils.throwIf(StringUtils.isBlank(tags), ErrorCode.PARAMS_ERROR, "竞赛标签不能为空");
            ThrowUtils.throwIf(competitionType == 0 && ObjectUtils.isEmpty(examId), ErrorCode.PARAMS_ERROR, "线上竞赛请先选择竞赛考试");
        }

        // 有参数则校验
        if (StringUtils.isNotBlank(competitionName) && competitionName.length() > 40) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "队名过长");
        }
        if (StringUtils.isNotBlank(announce) && announce.length() > 80) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "公告内容过长");
        }
        if (ObjectUtils.isNotEmpty(maxNum) && maxNum % 2 != 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "竞赛队伍最大个数不能为空或单数");
        }
        if (ObjectUtils.isNotEmpty(maxNum) && maxNum > 1024) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "竞赛队伍最大个数不能多于1024队");
        }
        if (StringUtils.isNotBlank(address) && address.length() > 60) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "地址输入不合法，不能超过60字符");
        }
    }

    /**
     * 获取查询包装类
     *
     * @param competitionQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Competition> getQueryWrapper(CompetitionQueryRequest competitionQueryRequest) {
        QueryWrapper<Competition> queryWrapper = new QueryWrapper<>();
        if (competitionQueryRequest == null) {
            return queryWrapper;
        }

        String searchText = competitionQueryRequest.getSearchText();
        String sortField = competitionQueryRequest.getSortField();
        String sortOrder = competitionQueryRequest.getSortOrder();
        String competitionStatus = competitionQueryRequest.getCompetitionStatus();
        Long id = competitionQueryRequest.getId();
        List<String> tagList = competitionQueryRequest.getTags();

        Long userId = competitionQueryRequest.getUserId();

        // 拼接查询条件
        if (StringUtils.isNotBlank(searchText)) {
            queryWrapper.and(qw -> qw.like("competitionName", searchText).or()
                    .like("announce", searchText).or()
                    .like("tags", searchText));
        }

        if (CollUtil.isNotEmpty(tagList)) {
            for (String tag : tagList) {
                queryWrapper.like("tags", "\"" + tag + "\"");
            }
        }
        queryWrapper.eq(StringUtils.isNotBlank(competitionStatus), "competitionStatus", competitionStatus);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    @Override
    public CompetitionVO getCompetitionVO(Competition competition, HttpServletRequest request) {
        return getCompetitionVO(competition);
    }

    public CompetitionVO getCompetitionVO(Competition competition) {
        CompetitionVO competitionVO = CompetitionVO.objToVo(competition);
        Long userId = competition.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
        }
        UserVO leaderUserVo = userService.getUserVO(user);
        competitionVO.setUser(leaderUserVo);
        return competitionVO;
    }

    @Override
    public Page<CompetitionVO> getCompetitionVOPage(Page<Competition> competitionPage, HttpServletRequest request) {
        List<Competition> competitionList = competitionPage.getRecords();
        Page<CompetitionVO> competitionVoPage = new Page<>(competitionPage.getCurrent(), competitionPage.getSize(), competitionPage.getTotal());
        if (CollUtil.isEmpty(competitionList)) {
            return competitionVoPage;
        }
        // 填充信息
        List<CompetitionVO> competitionVOList = competitionList.stream().map(this::getCompetitionVO).collect(Collectors.toList());
        competitionVoPage.setRecords(competitionVOList);
        return competitionVoPage;
    }
}




